package com.hxk.juc.thread.volatileLearn;

/**
 *volatile 是java轻量级的同步机制
 *  volatile的三大特性
 *      1、保证可见性
 *      2、不保证原子性
 *      3、禁止指令重排
 *  本case主要是对volatile的【禁止指令重排】特性的描述，
 *      由于指令指令重排是java虚拟机底层的一直实现，使用代码无法演示，这里用一个例子演示说明即可，
 *      【重点】：指令重排在单线程下不会引发什么问题，只有在多线程环境下才会发生
 * 所谓指令重排序，就是出于优化考虑，CPU执行指令的顺序跟程序员自己编写的顺序不一致。
 *  就好比一份试卷，题号是老师规定的，是程序员规定的，但是考生（CPU）可以先做选择，也可以先做填空。
 */
public class VolatileCase3 {

    public static void main(String[] args) {
        int x = 11; //语句1
        int y = 12; //语句2
        x = x + 5;  //语句3
        y = x * x;  //语句4

        /***
         * 【重排的前提条件是：数据依赖性】
         * 以上例子，可能出现的执行顺序有以下三种情况：
         *      第一种：1234、
         *      第二种：2134、
         *      第三种：1342，
         * 这三个都没有问题，
         * 最终结果都是x = 16，y=256。
         * 但是如果是4开头，就有问题了，因为y依赖于数据a。所以不可能会出现语句4在前的执行顺序
         * volatile底层是用CPU的内存屏障（Memory Barrier）指令来实现的，有两个作用，
         *  一个是保证特定操作的顺序性，
         *  二是保证变量的可见性。在指令之间插入一条Memory Barrier指令，告诉编译器和CPU，在Memory Barrier指令之间的指令不能被重排序。
         */
    }
}
